module axi_master_writer #(
    parameter ADDR_BASE = 32'h4000_0000
)(
    input  wire        clk,
    input  wire        reset,
    input  wire        start,         // 启动写操作
    input  wire [31:0] data_in,       // 来自fake_systolic_muxed
    input  wire        data_valid,    // 来自fake_systolic_muxed
    input  wire        data_done,     // fake_systolic_muxed输出完成
    output reg         data_ready,    // 可用于流控（本例可不接）

    // AXI4 写通道
    output reg  [31:0] M_AXI_AWADDR,
    output reg         M_AXI_AWVALID,
    input  wire        M_AXI_AWREADY,
    output reg  [31:0] M_AXI_WDATA,
    output reg  [3:0]  M_AXI_WSTRB,
    output reg         M_AXI_WVALID,
    input  wire        M_AXI_WREADY,
    input  wire [1:0]  M_AXI_BRESP,
    input  wire        M_AXI_BVALID,
    output reg         M_AXI_BREADY,

    output reg         axi_done       // AXI写完成
);

    // 状态机定义
    typedef enum logic [1:0] {
        IDLE = 2'b00,
        WRITE_ADDR = 2'b01,
        WRITE_DATA = 2'b10,
        WRITE_RESP = 2'b11
    } state_t;

    state_t state, state_next;

    reg [7:0] write_cnt; // 0~255
    reg [31:0] addr_reg;

    // 状态机时序
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            write_cnt <= 8'd0;
            addr_reg <= ADDR_BASE;
            axi_done <= 1'b0;
        end else begin
            state <= state_next;
            if (state == IDLE && start) begin
                write_cnt <= 8'd0;
                addr_reg <= ADDR_BASE;
                axi_done <= 1'b0;
            end else if (state == WRITE_RESP && M_AXI_BVALID && M_AXI_BREADY) begin
                if (write_cnt == 8'd255) begin
                    axi_done <= 1'b1;
                end else begin
                    write_cnt <= write_cnt + 1'b1;
                    addr_reg <= addr_reg + 4; // 32bit递增
                end
            end
        end
    end

    // 状态机组合
    always @(*) begin
        // 默认值
        M_AXI_AWADDR  = addr_reg;
        M_AXI_AWVALID = 1'b0;
        M_AXI_WDATA   = data_in;
        M_AXI_WSTRB   = 4'b1111;
        M_AXI_WVALID  = 1'b0;
        M_AXI_BREADY  = 1'b0;
        data_ready    = 1'b0;
        state_next    = state;

        case (state)
            IDLE: begin
                if (start) begin
                    state_next = WRITE_ADDR;
                end
            end
            WRITE_ADDR: begin
                M_AXI_AWVALID = 1'b1;
                if (M_AXI_AWREADY) begin
                    state_next = WRITE_DATA;
                end
            end
            WRITE_DATA: begin
                if (data_valid) begin
                    M_AXI_WVALID = 1'b1;
                    data_ready = 1'b1;
                    if (M_AXI_WREADY) begin
                        state_next = WRITE_RESP;
                    end
                end
            end
            WRITE_RESP: begin
                M_AXI_BREADY = 1'b1;
                if (M_AXI_BVALID) begin
                    if (write_cnt == 8'd255) begin
                        state_next = IDLE;
                    end else begin
                        state_next = WRITE_ADDR;
                    end
                end
            end
        endcase
    end

endmodule 